<?php
namespace app\user\controller;

use think\Controller;
use Verify\GeetestLib;
use Verify\Verify;
use Utils\AjaxMsg;
use app\user\model\User as UserModel;
use app\user\model\Smscode;
use app\user\model\TryAuth;
use app\app\model\App;
use think\Request;

class Api extends Controller {
	public function getcode(){
		echo Verify::getCode();
    }

    //检验手机号
    public function validateMobileNum(): void {
        $msg = new AjaxMsg();
        $mobileNum = input('post.mobileNum');
        $mobileNumInt = intval($mobileNum);
        //判断用户是否存在
        if(!UserModel::getByMobileNum($mobileNumInt)){
            $msg->addFocus('mobileNum', false, '手机号未注册');
            $msg->setStatus(-1);
            echo $msg;
            return;
        } else {
            $msg->addFocus('mobileNum', true);
            $msg->setData([
                'time' => time(),
                'countdown' => Smscode::getCountdownTime($mobileNumInt, Smscode::LOGIN),
            ]);
            $msg->setStatus(1);
            echo $msg;
        }
    }

    //发送短信验证码
    public function sendSmsCode(): void {
        $msg = new AjaxMsg();
        $mobileNum = input('post.mobileNum', 0, 'intval');
        //检验极验验证码
        if(!Verify::check()){
            $msg->addMsg('error', 'ERR::INCORRECT_CAPTCHA', '提示', '未通过验证，请重试');
            echo $msg;
            return;
        }
        //检验手机号是否正确
        if(!Smscode::isValidMobileNum($mobileNum)){
            $msg->addMsg('error', 'ERR::INCORRECT_MOBILE_NUMBER', '提示', '手机号格式错误');
            $msg->addFocus('mobileNum', false, '手机号格式错误');
            echo $msg;
            return;
        }
        //判断用户是否存在
        if(!UserModel::getByMobileNum($mobileNum)){
            $msg->addMsg('error', 'ERR::INCORRECT_MOBILE_NUMBER', '提示', '用户不存在');
            $msg->addFocus('mobileNum', false, '用户不存在');
            $msg->setStatus(-1);
            echo $msg;
            return;
        }
        //发送短信
        $sender = Smscode::getSender($mobileNum, Smscode::LOGIN);
        if($sender){
            $result = $sender->sendSms();
            if($result === 'OK'){ //发送成功
                $msg->addMsg('success', 'OK', '提示', '验证码已发送');
                $msg->setData([
                    'countdown' => $sender->send_time + Smscode::COUNTDOWN,
                    'time' => time(),
                ]);
                $msg->setStatus(1);
                echo $msg;
            } else { //发送失败
                $msg->addMsg('error', 'ERR::' . $result, '错误', Smscode::getErrorMsg($result));
                echo $msg;
            }
        } else {
            $msg->addMsg('error', 'ERR::SERVER', '提示', '服务器错误，如果经常出现，请联系管理员。');
            echo $msg;
        }
    }

    public function validateUserName(): void {
        $msg = new AjaxMsg();
        $userName = input('post.userName');
        //判断用户是否存在
        $user = UserModel::getByUsername($userName);
        if(!$user){
            $msg->addFocus('userName', false, '用户不存在，请检查是否填写正确');
            $msg->setStatus(-1);
            echo $msg;
        } else {
            $shouldUseCaptcha = TryAuth::shouldUseCaptcha(get_client_ip(), $user->uid);

            $msg->addFocus('userName', true);
            $msg->setStatus(1);
            $msg->setData([
                'shouldUseCaptcha' => $shouldUseCaptcha,
            ]);
            echo $msg;
        }
    }

    public function validateSmsVerifyCode(): void {
        $msg = new AjaxMsg();
        $mobileNum = input('post.mobileNum', 0, 'intval');
        $code = input('post.smsVerifyCode', 0, 'intval');

        $user = UserModel::getByMobileNum($mobileNum);
        if(!$user){
            $msg->addFocus('mobileNum', false, '用户不存在');
            $msg->setStatus(-1);
            echo $msg;
        } else {
            $shouldUseCaptcha = TryAuth::shouldUseCaptcha(get_client_ip(), $user->uid);
            if(!$shouldUseCaptcha){ //在允许尝试的范围内
                if(Smscode::verify($mobileNum, Smscode::LOGIN, $code)){
                    $msg->addFocus('smsVerifyCode', true);
                    $msg->setStatus(1);
                } else {
                    $msg->addFocus('smsVerifyCode', false, '短信验证码错误');
                }
            }
            TryAuth::increaseTry(get_client_ip(), $user->uid);
            $shouldUseCaptcha = TryAuth::shouldUseCaptcha(get_client_ip(), $user->uid);
            $msg->setData([
                'shouldUseCaptcha' => $shouldUseCaptcha,
            ]);
            echo $msg;
        }
    }

    public function login(Request $request): void {
        $msg = new AjaxMsg();

        $userName = $request->username;
        $mobileNum = $request->mobileNum;
        if($userName){ //用户名密码登录
            $this->loginByUsername($request);
        } elseif($mobileNum){ //手机号登录
            $this->loginBySmsVerifyCode($request);
        } else {
            $msg->addMsg('error', 'ERR::INCORRECT_INPUT', '提示', '输入信息错误');
            echo $msg;
        }
    }

    private function loginByUsername(Request $request): void {
        $msg = new AjaxMsg();

        $userName = $request->username;
        $password = $request->password;

        $user = UserModel::getByUsername($userName);
        if(!$user){
            $msg->addFocus('username', false, '用户不存在');
            $msg->setStatus(-1);
            echo $msg;
            return;
        }

        $shouldUseCaptcha = TryAuth::shouldUseCaptcha(get_client_ip(), $user->uid);
        if($shouldUseCaptcha){
            //检验验证码
            if(!Verify::check()){
                $msg->setData([
                    'shouldUseCaptcha' => true,
                ]);
                $msg->addMsg('error', 'ERR::INCORRECT_CAPTCHA', '提示', '未通过验证，请重试');
                echo $msg;
                return;
            }
        }

        //增加尝试登录记录
        TryAuth::increaseTry(get_client_ip(), $user->uid);
        $shouldUseCaptcha = TryAuth::shouldUseCaptcha(get_client_ip(), $user->uid);
        $msg->setData([
            'shouldUseCaptcha' => $shouldUseCaptcha,
        ]);

        //开始验证密码
        if($user->checkPassword($password)){
            //验证成功，进入下一步
            $msg->addFocus('passWord', true);
            $this->continueLogin($user, $msg);
        } else {
            $msg->addFocus('passWord', false, '密码不正确');
            echo $msg;
        }
    }

    private function loginBySmsVerifyCode(Request $request){
        $msg = new AjaxMsg();

        $mobileNum = $request->mobileNum;
        $smsVerifyCode = $request->smsVerifyCode;

        $user = UserModel::getByMobileNum($mobileNum);
        if(!$user){
            $msg->addFocus('mobileNum', false, '用户不存在');
            $msg->setStatus(-1);
            echo $msg;
        } else {
            $shouldUseCaptcha = TryAuth::shouldUseCaptcha(get_client_ip(), $user->uid);
            if($shouldUseCaptcha){
                //检验验证码
                if(!Verify::check()){
                    $msg->setData([
                        'shouldUseCaptcha' => true,
                    ]);
                    $msg->addMsg('error', 'ERR::INCORRECT_CAPTCHA', '提示', '未通过验证，请重试');
                    echo $msg;
                    return;
                }
            }

            //增加尝试登录的信息
            TryAuth::increaseTry(get_client_ip(), $user->uid);
            $shouldUseCaptcha = TryAuth::shouldUseCaptcha(get_client_ip(), $user->uid);
            $msg->setData([
                'shouldUseCaptcha' => $shouldUseCaptcha,
            ]);
            
            if(Smscode::verify($mobileNum, Smscode::LOGIN, $smsVerifyCode)){
                //验证成功，进入下一步
                $msg->addFocus('smsVerifyCode', true);
                $this->continueLogin($user, $msg);
            } else {
                $msg->addFocus('smsVerifyCode', false, '短信验证码错误');
                echo $msg;
            }
        }
    }

    /**
     * 登录后处理
     */
    private function continueLogin(UserModel $user, AjaxMsg $msg){
        $rememberLogin = input('param.remember', false, 'boolval');

        //设置登录Cookie
        $user->setLogin($rememberLogin);

        $data = $msg->getData();

        $data['shouldUseCaptcha'] = TryAuth::shouldUseCaptcha(get_client_ip(), $user->uid);

        //取得同步登录URL
        $data['syncLoginUrl'] = App::getSyncLoginUrl($user->uid, $rememberLogin);
        
        //返回值
        $msg->setData($data);
        $msg->addMsg('success', 'OK', '提示', '登录成功，正在跳转……');
        $msg->setStatus(1);
        echo $msg;

        /*
         * 得想想怎么验证重定向到的域名，防止csrf攻击
         */
    }
}